package cn.wizzer.app.user.modules.service.impl;

import cn.wizzer.app.sys.modules.models.SysMsg;
import cn.wizzer.app.sys.modules.services.SysMsgService;
import cn.wizzer.app.user.modules.models.GroupApply;
import cn.wizzer.app.user.modules.models.GroupInfo;
import cn.wizzer.app.user.modules.models.enums.GroupApplyEnum;
import cn.wizzer.app.user.modules.models.vo.GroupApplyVo;
import cn.wizzer.app.user.modules.services.GroupApplyService;
import cn.wizzer.app.user.modules.services.GroupInfoService;
import cn.wizzer.app.user.modules.services.GroupMemberService;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;

import java.util.List;

@IocBean(args = {"refer:dao"})
@Service(interfaceClass = GroupApplyService.class)
public class GroupApplyServiceImpl extends BaseServiceImpl<GroupApply> implements GroupApplyService{

    public GroupApplyServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private CommonDBService dbService;

    @Inject
    private GroupInfoService groupInfoService;

    @Inject
    private GroupMemberService groupMemberService;

    @Inject
    @Reference
    private SysMsgService userMsgService;

    @Override
    public Pagination listPage(String groupName, String userKeyword, String status, String[] searchDate, int pageNumber, int pageSize) {
        Sql sql = Sqls.create("SELECT i.groupName, u.nickName, u.userName, ga.* " +
                "FROM group_apply ga ");
        Sql joinSql = Sqls.create("LEFT JOIN user u ON u.id = ga.userId " +
                "LEFT JOIN group_info i ON i.id = ga.groupId " +
                "$condition ");
        Cnd cnd = Cnd.where("ga.delFlag", "=", 0);
        if (Strings.isNotBlank(groupName)) {
            groupName = "%" + groupName + "%";
            cnd.and("i.groupName", "LIKE", groupName);
        }
        if (Strings.isNotBlank(userKeyword)) {
            userKeyword = "%" + userKeyword + "%";
            cnd.and(Cnd.exps("u.nickName", "LIKE", userKeyword)
                    .or("u.userName", "LIKE", userKeyword));
        }
        if (Strings.isNotBlank(status)) {
            cnd.and("ga.status", "=", status);
        }
        if (searchDate != null && searchDate.length > 0) {
            cnd.and("ga.ctAt", ">=", Times.d2TS(Times.D(searchDate[0])));
            cnd.and("ga.ctAt", "<=", Times.d2TS(Times.D(searchDate[1])));
        }
        joinSql.setCondition(cnd);
        sql.appendSourceSql(joinSql.toString());
        sql.appendSourceSql("ORDER BY ga.ctAt DESC");
        return dbService.listPage(GroupApplyVo.class, pageNumber, pageSize, sql.toString());
    }

    @Override
    @Aop(TransAop.REPEATABLE_READ)
    public void agree(GroupApply groupApply) {
        groupApply.setStatus(GroupApplyEnum.AGREED);
        this.update(groupApply);
        groupMemberService.addMember(groupApply.getUserId(), groupApply.getGroupId());
    }


    @Override
    public void refuse(GroupApply groupApply, String opBy) {
        groupApply.setStatus(GroupApplyEnum.REFUSED);
        this.update(groupApply);
        GroupInfo fetch = groupInfoService.fetch(groupApply.getGroupId());
        // 给用户发送通知
        SysMsg userMsg = userMsgService.createMsg("member",
                "Notice of Join the group failure",
                "Sorry,group '"+ fetch.getGroupName() +"' refused you to join", opBy);
        userMsgService.saveMsg(userMsg, new String[]{groupApply.getUserId()});
    }


    @Override
    public void apply(String appid, String groupId, String content) {
        GroupApply groupApply = new GroupApply();
        groupApply.setUserId(appid);
        groupApply.setGroupId(groupId);
        groupApply.setContent(content);
        groupApply.setStatus(GroupApplyEnum.APPLYING);
        // 如果已经申请，则update。不重复insert
        Cnd cnd = Cnd.where("userId", "=", groupApply.getUserId()).and("groupId", "=", groupApply.getGroupId());
        GroupApply old = this.fetch(cnd);
        if (null != old) {
            groupApply.setId(old.getId());
            groupApply.setDelFlag(false);
            groupApply.setCtAt(Times.getTS());
        }
        this.insertOrUpdate(groupApply);
    }

}
